﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Management.Automation;
using System.Collections;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.Office.Server.Diagnostics;
using Microsoft.SharePoint.Administration;
using System.IO;
using Microsoft.SharePoint.Workflow;

namespace spdevstore.spreports
{
    [Cmdlet(VerbsCommon.Get, "rp.InProgressWorkflows", SupportsShouldProcess = true)]
    public class GetInProgressWorkflows : PSCmdlet
    {

        #region Parameters
        [Parameter(Position = 0,
        ParameterSetName = "",
        Mandatory = true,
        ValueFromPipelineByPropertyName = true,
        HelpMessage = "Enter Scope - Farm, WebApplication, SiteCollection or Site ")]
        public string Scope;

        [Parameter(Position = 1,
        ParameterSetName = "",
        Mandatory = true,
        ValueFromPipelineByPropertyName = true,
        HelpMessage = "Enter URL as per Scope")]
        public string Site;

        [Parameter(Position = 2,
        ParameterSetName = "",
        Mandatory = true,
        ValueFromPipelineByPropertyName = true,
        HelpMessage = "Enter Folder Path to save SPReport")]
        public string ResultsPath;


        #endregion

        protected override void ProcessRecord()
        {
            StreamWriter streamWriter = null;
            String resultPath = String.Empty;
            String filename = String.Empty;
            filename = "rp.InProgressWorkflows.csv";

            //Build File Path for Results
            resultPath = Path.Combine(ResultsPath, filename);

            //Create or open existing file using Stream writer class with UTF Encoding and Overwrite option
            streamWriter = new StreamWriter(resultPath, false, Encoding.UTF8);
            streamWriter.WriteLine("Web Application, Site Collection, Site URL, Site Name, List, Workflow Instance, Workflow Task List, Workflow Association ID, Workflow Name, Workflow Status, Item Title, Item URL, Workflow Modified Date");

            if (Scope == "Farm")
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {

                    try
                    {
                        SPServiceCollection services = SPFarm.Local.Services;
                        foreach (SPService curService in services)
                        {
                            if (curService is SPWebService)
                            {
                                SPWebService currentwebservice = (SPWebService)curService;
                                foreach (SPWebApplication webapp in currentwebservice.WebApplications)
                                {

                                    SPSite sitecol = null;
                                    try
                                    {
                                        using (sitecol = new SPSite(Site))
                                        {
                                            foreach (SPSite site in webapp.Sites)
                                            {
                                                foreach (SPWeb subWeb in site.AllWebs)
                                                {
                                                    InProgressWorkflows(subWeb, streamWriter, resultPath);
                                                    subWeb.Dispose();
                                                }
                                            }
                                        }
                                    }

                                    catch (Exception ex)
                                    {
                                         
                                        ThrowTerminatingError(new ErrorRecord(ex, "0", ErrorCategory.NotSpecified, null));
                                    }

                                }
                            }

                        }

                    }
                    catch (Exception ex)
                    {
                         
                        ThrowTerminatingError(new ErrorRecord(ex, "0", ErrorCategory.NotSpecified, null));
                    }

                });
            }

            else if (Scope == "WebApplication")
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    SPSite sitecol = null;
                    try
                    {
                        using (sitecol = new SPSite(Site))
                        {
                            foreach (SPSite site in sitecol.WebApplication.Sites)
                            {
                                foreach (SPWeb subWeb in site.AllWebs)
                                {
                                    InProgressWorkflows(subWeb, streamWriter, resultPath);
                                    subWeb.Dispose();
                                }
                            }
                        }
                    }

                    catch (Exception ex)
                    {
                         
                        ThrowTerminatingError(new ErrorRecord(ex, "0", ErrorCategory.NotSpecified, null));
                    }
                });
            }

            else if (Scope == "SiteCollection")
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    SPSite sitecol = null;
                    try
                    {
                        using (sitecol = new SPSite(Site))
                        {
                            foreach (SPWeb subWeb in sitecol.AllWebs)
                            {
                                InProgressWorkflows(subWeb, streamWriter, resultPath);
                                subWeb.Dispose();
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                         
                        ThrowTerminatingError(new ErrorRecord(ex, "0", ErrorCategory.NotSpecified, null));
                    }

                });
            }

            else if (Scope == "Site")
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    SPSite site = null;
                    try
                    {
                        using (site = new SPSite(Site))
                        {

                            SPWeb subWeb = site.OpenWeb();
                            InProgressWorkflows(subWeb, streamWriter, resultPath);
                            subWeb.Dispose();
                        }

                    }
                    catch (Exception ex)
                    {
                         
                        ThrowTerminatingError(new ErrorRecord(ex, "0", ErrorCategory.NotSpecified, null));
                    }

                });
            }
            else
            {
                WriteObject(string.Empty);
                WriteObject(string.Format("Invalid Scope entered as Parameter. Please verify and run the script. Scope should be Farm/WebApplication"));

            }
            streamWriter.Close();
        }
        private void InProgressWorkflows(SPWeb web, StreamWriter streamWriter, String resultPath)
        {
           // streamWriter.WriteLine("Hello" + "," + web.Url);
            foreach (SPList list in web.Lists)
            {
                try
                {
                    //Retreive all items to find the Active workflows
                    foreach (SPListItem item in list.Items)
                    {
                        foreach (SPWorkflow workfflow in item.Workflows)
                        {
                            //Only report on incomplete workflows (In Progress)
                            if (!workfflow.IsCompleted)
                            {
                                //Write Active Workflow details into Reports file
                                streamWriter.WriteLine(web.Site.WebApplication.Name + "," + web.Site.RootWeb.Url + "," + web.Url + "," + web.Title + "," + item.ParentList.Title + "," + workfflow.InstanceId + "," + workfflow.TaskList + "," + workfflow.AssociationId + "," + "\"" + workfflow.ParentAssociation.Name + "\"" + "," +
                                workfflow.IsCompleted.ToString() + "," + "\"" + item.Title + "\"" + "," + item.Url + "," +
                                workfflow.Modified.ToShortDateString());
                            }

                        }
                    }
                }

                catch (Exception exception)
                {
                     
                }

            }

        }
    }
}

